import { requestClient, oidcRequestClient } from '#/api/request';
import {
  authConfig,
  generatePKCE,
  generateCode,
  serviceInfoDict,
} from '#/utils/daprplus';

/** 授权请求参数 */
export interface AuthorizeParams {
  client_id: string;
  redirect_uri: string;
  response_type: string;
  scope: string;
  state: string;
  code_challenge: string;
  code_challenge_method: string;
}

/** Token交换请求参数 */
export interface ExchangeTokenParams {
  grant_type: string;
  client_id: string;
  code: string;
  redirect_uri: string;
  code_verifier: string;
}

/** Token交换响应结果 */
export interface ExchangeTokenResult {
  access_token: string;
  token_type: string;
  expires_in: number;
  scope: string;
  refresh_token?: string;
  id_token: string;
}

/** 刷新Token请求参数 */
export interface RefreshTokenParams {
  grant_type: string;
  refresh_token: string;
  client_id: string;
}

/**
 * OIDC授权重定向
 * @description 生成PKCE并重定向到OIDC服务的授权端点
 */
export async function loginRedirectApi(): Promise<void> {
  const config = authConfig();
  const url = new URL(`${config.authority}/connect/authorize`);
  const params: AuthorizeParams = {
    client_id: config.clientId,
    redirect_uri: config.redirectUri,
    response_type: 'code',
    scope: config.scopes,
    state: generateCode(),
    code_challenge: await generatePKCE(),
    code_challenge_method: 'S256',
  };
  Object.entries(params).forEach(([key, value]) =>
    url.searchParams.append(key, value),
  );
  window.location.href = url.toString();
}

/**
 * 交换授权码获取token
 * @param code 授权码
 * @param codeVerifier PKCE验证码
 * @returns Token响应结果
 */
export async function exchangeTokenApi(
  code: string,
  codeVerifier: string,
): Promise<ExchangeTokenResult> {
  const config = authConfig();
  const tokenRequest: ExchangeTokenParams = {
    grant_type: 'authorization_code',
    client_id: config.clientId,
    code,
    redirect_uri: config.redirectUri,
    code_verifier: codeVerifier,
  };

  return oidcRequestClient.post<ExchangeTokenResult>(
    '/connect/token',
    tokenRequest,
    {
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
      },
      responseReturn: 'body',
    },
  );
}

/**
 * 刷新accessToken
 * @param refreshToken 刷新令牌
 */
export async function refreshTokenApi(
  refreshToken: string,
): Promise<ExchangeTokenResult> {
  const config = authConfig();
  const refreshRequest: RefreshTokenParams = {
    grant_type: 'refresh_token',
    refresh_token: refreshToken,
    client_id: config.clientId,
  };

  const result = await oidcRequestClient.post<ExchangeTokenResult>(
    '/connect/token',
    refreshRequest,
  );
  return result;
}

/**
 * 退出登录
 * @description 重定向到OIDC服务的end_session_endpoint
 */
export function logoutApi(idToken: string | null) {
  const config = authConfig();
  const url = new URL(`${config.authority}/connect/endsession`);
  const params = {
    post_logout_redirect_uri: import.meta.env
      .VITE_OIDC_POST_LOGOUT_REDIRECT_URI,
    id_token_hint: idToken,
  };
  Object.entries(params).forEach(([key, value]) => {
    if (value) {
      url.searchParams.append(key, value);
    }
  });
  window.location.href = url.toString();
}

/**
 * 获取用户权限码
 * @returns 返回用户权限码数组
 */
export async function getAccessCodesApi(): Promise<string[]> {
  const codes = await requestClient.get<string[]>(`/api/roleResource/access`, {
    responseReturn: 'data',
  });
  return codes;
}
